#include "stdafx.h"
#include "httpdownload.h"

#include <QNetworkRequest>
#include <QDebug>

// 定义下载状态常量
const QString STATE_IDLE = "空闲";
const QString STATE_DOWNLOADING = "下载中";
const QString STATE_PAUSED = "已暂停";
const QString STATE_FINISHED = "已完成";
const QString STATE_ERROR = "错误";

HttpDownload::HttpDownload(QObject* parent)
    : QObject(parent)
    , m_networkManager(nullptr)
    , m_reply(nullptr)
    , m_file(nullptr)
    , m_isUserCanceled(false)
{
    // 初始化下载状态
    m_currentState = STATE_IDLE;

    // 初始化网络管理器
    initNetworkManager();

    qDebug() << "HttpDownload对象已创建";
}

HttpDownload::~HttpDownload()
{
    // 清理资源
    cleanupReply();

    if (m_networkManager) {
        delete m_networkManager;
        m_networkManager = nullptr;
    }

    qDebug() << "HttpDownload对象已销毁";
}

void HttpDownload::initNetworkManager()
{
    // 创建网络访问管理器
    m_networkManager = new QNetworkAccessManager(this);

    qDebug() << "网络管理器初始化完成";
}

void HttpDownload::startDownload(const QUrl& url, const QString& filePath)
{
    // 检查URL是否有效
    if (!url.isValid()) {
        emit downloadError("无效的URL地址");
        return;
    }

    // 检查文件路径是否有效
    if (filePath.isEmpty()) {
        emit downloadError("文件保存路径不能为空");
        return;
    }

    // 如果正在下载，先取消当前下载
    if (m_reply && m_reply->isRunning()) {
        cancelDownload();
    }

    // 保存URL和文件路径
    m_downloadUrl = url;
    m_saveFilePath = filePath;
    m_isUserCanceled = false;

    // 创建本地文件
    m_file = new QFile(filePath);
    if (!m_file->open(QIODevice::WriteOnly)) {
        emit downloadError("无法创建文件: " + filePath);
        delete m_file;
        m_file = nullptr;
        return;
    }

    // 创建网络请求
    QNetworkRequest request(url);

    // 设置HTTP请求头
    request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true);

    // 发送GET请求开始下载
    m_reply = m_networkManager->get(request);

    // 连接信号和槽
    connect(m_reply, &QNetworkReply::finished, this, &HttpDownload::onReplyFinished);
    connect(m_reply, &QNetworkReply::downloadProgress, this, &HttpDownload::onDownloadProgress);
    connect(m_reply, &QNetworkReply::readyRead, this, &HttpDownload::onReadyRead);
    connect(m_reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::errorOccurred),
        this, &HttpDownload::onNetworkError);

    // 更新下载状态
    setState(STATE_DOWNLOADING);

    qDebug() << "开始下载:" << url.toString() << "保存到:" << filePath;
}

void HttpDownload::pauseDownload()
{
    if (m_reply && m_reply->isRunning()) {
        // 暂停下载（实际是取消当前请求，但保留文件）
        m_reply->abort();
        setState(STATE_PAUSED);
        qDebug() << "下载已暂停";
    }
}

void HttpDownload::resumeDownload()
{
    if (m_currentState == STATE_PAUSED && !m_downloadUrl.isEmpty()) {
        // 重新开始下载（这里简化处理，实际应该支持断点续传）
        startDownload(m_downloadUrl, m_saveFilePath);
        qDebug() << "继续下载";
    }
}

void HttpDownload::cancelDownload()
{
    m_isUserCanceled = true;

    if (m_reply && m_reply->isRunning()) {
        // 取消下载
        m_reply->abort();
        qDebug() << "下载已取消";
    }

    // 清理临时文件
    if (m_file) {
        m_file->remove(); // 删除未完成的文件
        delete m_file;
        m_file = nullptr;
    }

    setState(STATE_IDLE);
}

QString HttpDownload::getDownloadState() const
{
    return m_currentState;
}

void HttpDownload::onReplyFinished()
{
    if (!m_reply) {
        return;
    }

    // 检查HTTP状态码
    QVariant statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (statusCode.isValid()) {
        int status = statusCode.toInt();
        qDebug() << "HTTP状态码:" << status;

        // 处理重定向
        if (status >= 300 && status < 400) {
            QUrl redirectUrl = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
            if (redirectUrl.isValid()) {
                qDebug() << "重定向到:" << redirectUrl.toString();
                startDownload(redirectUrl, m_saveFilePath);
                cleanupReply();
                return;
            }
        }
    }

    // 关闭文件
    if (m_file) {
        m_file->close();
        delete m_file;
        m_file = nullptr;
    }

    // 检查错误
    if (m_reply->error() != QNetworkReply::NoError && !m_isUserCanceled) {
        // 下载出错
        QString errorString = m_reply->errorString();
        emit downloadError("下载失败: " + errorString);
        setState(STATE_ERROR);
        qDebug() << "下载错误:" << errorString;
    }
    else if (!m_isUserCanceled) {
        // 下载成功完成
        emit downloadFinished(m_saveFilePath);
        setState(STATE_FINISHED);
        qDebug() << "下载完成:" << m_saveFilePath;
    }
    else {
        // 用户取消
        setState(STATE_IDLE);
        qDebug() << "下载被用户取消";
    }

    // 清理回复对象
    cleanupReply();
}

void HttpDownload::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    // 发射进度信号
    //发送进度到这个方法
   emit downloadProgress(bytesReceived, bytesTotal);

   //onDownloadProgress 接收进度
    // 调试输出进度信息
    if (bytesTotal > 0) {
        double percent = (double)bytesReceived / bytesTotal * 100;
        qDebug() << "下载进度:" << percent << "%" << bytesReceived << "/" << bytesTotal << "bytes";
    }
    else {
        qDebug() << "下载进度:未知大小" << bytesReceived << "bytes";
    }
}

void HttpDownload::onReadyRead()
{
    if (!m_reply || !m_file) {
        return;
    }

    // 读取所有可用数据并写入文件
    QByteArray data = m_reply->readAll();
    if (m_file->write(data) == -1) {
        // 写入文件失败
        emit downloadError("写入文件失败: " + m_file->errorString());
        cancelDownload();
    }
}

void HttpDownload::onNetworkError(QNetworkReply::NetworkError error)
{
    Q_UNUSED(error)

        if (!m_reply || m_isUserCanceled) {
            return;
        }

    QString errorString = m_reply->errorString();
    emit downloadError("网络错误: " + errorString);
    setState(STATE_ERROR);

    qDebug() << "网络错误:" << errorString;
}

void HttpDownload::cleanupReply()
{
    if (m_reply) {
        // 断开所有连接
        m_reply->disconnect();

        // 删除回复对象
        m_reply->deleteLater();
        m_reply = nullptr;
    }
}

void HttpDownload::setState(const QString& state)
{
    if (m_currentState != state) {
        m_currentState = state;
        emit stateChanged(state);
        qDebug() << "下载状态改变为:" << state;
    }
}